#!/bin/sh

export MINIKUBE_NAME="${MINIKUBE_NAME:-minikube}"
export MINIKUBE_CPUS="${MINIKUBE_CPUS:-8}"
export MINIKUBE_MEMORY="${MINIKUBE_MEMORY:-8GB}"
export MINIKUBE_DISK="${MINIKUBE_DISK:-40GB}"
export MINIKUBE_DRIVER="${MINIKUBE_DRIVER:-virtualbox}"
export MINIKUBE_CONTAINER_RUNTIME="${MINIKUBE_CONTAINER_RUNTIME:-containerd}"
export MINIKUBE_FEATURE_GATES="${MINIKUBE_FEATURE_GATES:-x}"

check_minikube_version() {
  if ! minikube version | grep -q -F 'minikube version: v1.34.0'
  then
    echo "minikube version v1.34.0 is required"
    return 1
  fi
}

get_k8s_env_version() {
  echo "minikube version $(minikube version | head -n 1 | cut -d ' ' -f 3)"
  echo
}

reuse_k8s() {
  check_minikube_version

  if ! minikube -p "$MINIKUBE_NAME" status > /dev/null 2>&1
  then
    reset_k8s
    return
  fi

  echo "Reusing minikube environment"
}

reset_k8s() {
  check_minikube_version
  echo "Setting up minikube environment..."

  delete_k8s

  if [ -n "$K8S_CACHE_PATH" ] \
    && [ "$MINIKUBE_DRIVER" = docker ]
  then
    echo "Setting up minikube containerd cache for $K8S_CACHE_PATH..."
    if [ "$K8S_CACHE_RESET" = true ]
    then
      docker run --rm -v "$K8S_CACHE_PATH:/containerd-cache" alpine \
        sh -ec 'rm -rf /containerd-cache/*'
    fi

    docker run --rm -v "$K8S_CACHE_PATH:/containerd-cache" alpine \
      sh -ec 'mkdir -p "/containerd-cache/volume"'
    if docker volume inspect minikube >/dev/null 2>&1 \
      && [ "$(docker volume inspect minikube 2>/dev/null \
        | jq '.[0]
          |  .Options.device == "'"$K8S_CACHE_PATH"'/volume"
             and .Options.o == "bind"
             and .Options.type == "none"')" != true ]
    then
      docker volume rm minikube
    fi
    if ! docker volume inspect minikube >/dev/null 2>&1
    then
      docker volume create --name minikube \
        --opt type=none --opt o=bind --opt "device=$K8S_CACHE_PATH/volume"
    fi
    docker run --rm -v "$K8S_CACHE_PATH:/containerd-cache" alpine \
      sh -ec '
        if test -d /containerd-cache/volume/lib/containerd \
          && ! test -d /containerd-cache/containerd
        then
          echo "Moving out containerd directory"
          mv /containerd-cache/volume/lib/containerd /containerd-cache/containerd
        fi
        if test -d /containerd-cache/boot-volume
        then
          echo "Restoring boot volume cache"
          rm -rf /containerd-cache/volume
          cp -a /containerd-cache/boot-volume /containerd-cache/volume
        fi
        if test -d /containerd-cache/containerd
        then
          echo "Restoring containerd directory"
          rm -rf /containerd-cache/volume/lib/containerd
          mv /containerd-cache/containerd /containerd-cache/volume/lib/containerd
        fi
        '
  fi

  if [ "$MINIKUBE_FEATURE_GATES" = "x" ]
  then
    MINIKUBE_FEATURE_GATES=""
    if [ "${K8S_VERSION%.*}" = 1.11 ]
    then
      MINIKUBE_FEATURE_GATES="PodShareProcessNamespace=true"
    fi
  fi

  minikube -p "$MINIKUBE_NAME" start --kubernetes-version "$K8S_VERSION" \
    --cpus "$MINIKUBE_CPUS" \
    --memory "$MINIKUBE_MEMORY" \
    --disk-size "$MINIKUBE_DISK" \
    --vm-driver "$MINIKUBE_DRIVER" \
    --container-runtime "$MINIKUBE_CONTAINER_RUNTIME" \
    --feature-gates "$MINIKUBE_FEATURE_GATES"
  minikube -p "$MINIKUBE_NAME" addons enable volumesnapshots

  if [ -n "$K8S_CACHE_PATH" ] \
    && [ "$MINIKUBE_DRIVER" = docker ] \
    && docker run --rm -v "$K8S_CACHE_PATH:/containerd-cache" alpine \
      sh -ec '
        ! test -d /containerd-cache/boot-volume \
          || test -d /containerd-cache/containerd
        '
  then
    echo "Replacing minikube containerd cache with $K8S_CACHE_PATH..."
    minikube -p "$MINIKUBE_NAME" stop
    docker run --rm -v "$K8S_CACHE_PATH:/containerd-cache" alpine \
      sh -ec '
        if ! test -d /containerd-cache/boot-volume
        then
          echo "Creating boot volume"
          mv /containerd-cache/volume/lib/containerd /containerd-cache/boot-containerd
          rm -f /containerd-cache/boot-volume/lib/minikube/images/*
          cp -a /containerd-cache/volume /containerd-cache/boot-volume
          mv /containerd-cache/boot-containerd /containerd-cache/volume/lib/containerd
        fi
        if test -d /containerd-cache/containerd
        then
          echo "Restoring containerd directory"
          rm -rf /containerd-cache/volume/lib/containerd
          mv /containerd-cache/containerd /containerd-cache/volume/lib/containerd
        fi
        '
    minikube -p "$MINIKUBE_NAME" start
  fi

  echo "...done"
}

upgrade_k8s() {
  check_minikube_version
  minikube -p "$MINIKUBE_NAME" start --kubernetes-version "$1"
  minikube -p "$MINIKUBE_NAME" addons enable storage-provisioner
}

delete_k8s() {
  check_minikube_version
  echo "Deleting minikube environment..."

  minikube -p "$MINIKUBE_NAME" stop || true
  minikube -p "$MINIKUBE_NAME" delete || true

  echo "...done"
}

load_image_k8s() {
  check_minikube_version

  local IMAGE_ID
  IMAGE_ID="$( (docker inspect --format '{{ .ID }}' "$1" 2>/dev/null || printf unknown) | grep -v '^$')"
  local MINIKUBE_IMAGE_ID
  MINIKUBE_IMAGE_ID="$( (minikube -p "$MINIKUBE_NAME" image ls --format json 2>/dev/null || printf '[]') | jq -r --arg image registry.gitlab.com/ongresinc/stackgres/stackgres/admin-ui:6884291a 'map(select(.repoTags|any(. == $image)))|if (.|length) > 0 then .[0].id else "unknown" end')"
  if [ "$IMAGE_ID" = unknown ] && [ "$MINIKUBE_IMAGE_ID" != unknown ]
  then
    echo "Image $1 already loaded in minikube environemnt $MINIKUBE_NAME"
    return
  fi
  if [ "$MINIKUBE_IMAGE_ID" = "$IMAGE_ID" ]
  then
    echo "Image $1 already loaded in minikube environemnt $MINIKUBE_NAME"
    return
  fi
  minikube -p "$MINIKUBE_NAME" image load --daemon "$1"

  echo "Loaded image $1 in minikube environemnt $MINIKUBE_NAME"
}

pull_image_k8s() {
  check_minikube_version

  if [ "$MINIKUBE_DRIVER" != docker ]
  then
    echo "Can not pull image in internal repository since MINIKUBE_DRIVER is not set to docker"
    return 1
  fi
  local AUTH
  AUTH="$(jq -r '.auths|to_entries|.[]|.key + "|" + .value.auth' "${HOME}/.docker/config.json" \
    | grep -F "${1%%/*}" | head -n 1 | cut -d '|' -f 2)"
  if [ -n "$AUTH" ]
  then
    minikube -p "$MINIKUBE_NAME" image pull --auth "$AUTH" "$1"
  else
    minikube -p "$MINIKUBE_NAME" image pull "$1"
  fi

  echo "Pulled image $1 in minikube environemnt $MINIKUBE_NAME"
}

tag_image_k8s() {
  check_minikube_version

  minikube -p "$MINIKUBE_NAME" image tag "$1" "$2"

  echo "Tagged image $1 as $2 in minikube environemnt"
}

excluded_clusterrolebindings() {
  echo "minikube-rbac"
  echo "storage-provisioner"
}

get_k8s_versions() {
  cat << EOF
1.11.10
1.12.10
1.13.12
1.14.10
1.14.9
1.15.11
1.15.6
1.16.3
1.16.9
1.17.5
1.18.2
EOF
}
